/*
 * @brief Sensor Hub demo application (implementation file)
 *
 * @note
 * Copyright(C) NXP Semiconductors, 2015
 * All rights reserved.
 *
 * @par
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * LPC products.  This software is supplied "AS IS" without any warranties of
 * any kind, and NXP Semiconductors and its licensor disclaim any and
 * all warranties, express or implied, including all implied warranties of
 * merchantability, fitness for a particular purpose and non-infringement of
 * intellectual property rights.  NXP Semiconductors assumes no responsibility
 * or liability for the use of the software, conveys no license or rights under any
 * patent, copyright, mask work right, or any other intellectual property rights in
 * or to any products. NXP Semiconductors reserves the right to make changes
 * in the software without notification. NXP Semiconductors also makes no
 * representation or warranty that such application will be suitable for the
 * specified use without further testing or modification.
 *
 * @par
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, under NXP Semiconductors' and its
 * licensor's relevant copyrights in the software, without fee, provided that it
 * is used in conjunction with NXP Semiconductors microcontrollers.  This
 * copyright, permission, and disclaimer notice must appear in all copies of
 * this code.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <popt.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "trace.h"
#include "gl_callback.h"
#include "gl_menu.h"
#include "gl_text.h"
#include "auto_rotate.h"

#include "sio_cmd.h"
#include "sio_info.h"
#include "sensors.h"
#include "teapot.h"
#include "recorder.h"

#include "sensorhal.h"
#include "sensor_demo.h"

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/

/*****************************************************************************
 * Private types/enumerations/variables
 ****************************************************************************/
#define OPT_PORT			0x0001
#define OPT_ABOUT			0x0002
#define OPT_TRACE			0x0004
#define OPT_INFO			0x0008
#define OPT_NO_SENSORS		0x0010
#define OPT_RECORD			0x0020
#define OPT_BATCH			0x0040
#define OPT_COMMAND			0x0080

static poptContext	optCon;

/*****************************************************************************
 * Private functions
 ****************************************************************************/

static void about(void)
{
	printf("Sensor Demo:\n");
	printf("Copyright (C) NXP Semiconductors, 2015\n");
	printf("All rights reserved.\n");
	printf("version: 0.5.1.0\n");
}

/*****************************************************************************
 * Public functions
 ****************************************************************************/


//------------------------------------------------------------------------------
// Main function
//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
	uint32_t	opt=0;
	int			idx=0;
	int			port = 0;														/* I2C=0, SPI=1 */
	int			trace_level = 0x00;												/* All=0x0f, INFO=0x04, DEBUG=0x02, CRITICAL=0x01, NONE=0x00 */
	char*		fn_rec = NULL;
	char*		cmd = NULL;

	struct poptOption optionsTable[] = {
		{ "port",		'p', POPT_ARG_INT,		&port,			'p', "I2C=0 or SPI=1. Fixed to I2C.",							NULL	},
		{ "about",		'a', POPT_ARG_NONE,		NULL,			'a', "Display information about the app.",						NULL	},
		{ "trace",		't', POPT_ARG_INT,		&trace_level,	't', "Trace bits: critical=1, debug=2, info=4, enter/exit=8",	NULL	},
		{ "info",		'i', POPT_ARG_NONE,		NULL,			'i', "Display USB sio information and exit.",					NULL	},
		{ "no-sensors",	'n', POPT_ARG_NONE,		NULL,			'n', "Do not start any sensors.",								NULL	},
		{ "record",		'r', POPT_ARG_STRING,	&fn_rec,		'r', "record=filename.bin: Record data to filename",			NULL	},
		{ "no-batch",	'b', POPT_ARG_NONE,		NULL,			'b', "Disable batch commands for enable/disable.",				NULL	},
		{ "cmd",		'c', POPT_ARG_STRING,	&cmd,			'c', "Send direct command to the sensorhub.",					NULL	},
		POPT_AUTOHELP
		POPT_TABLEEND
	};

//------------------------------------------------------------------------------
//  No buffering for Eclipse/CDT (bug 173732)
//
//	This won't harm anything but it's not required
//	for normal console operation.
//
//	Remove if you aren't using Eclipse/CDT.
//------------------------------------------------------------------------------
//	setvbuf(stdout, NULL, _IONBF, 0);
//	setvbuf(stdin, NULL, _IONBF, 0);

//------------------------------------------------------------------------------
//  Process arguments
//------------------------------------------------------------------------------
	optCon = poptGetContext(NULL, argc, (const char **)argv, optionsTable, 0);
	poptSetOtherOptionHelp(optCon, "[OPTIONS]*");
	while ((idx = poptGetNextOpt(optCon)) >= 0) {
		switch (idx) {
		case 'p':
			if ((port != 0) && (port != 1)) {
				printf("Port must be either 0 or 1\n");
				exit(0);
			}
			opt |= OPT_PORT;
			break;
		case 'a':
			opt |= OPT_ABOUT;
			break;
		case 't':
			opt |= OPT_TRACE;
			break;
		case 'i':
			opt |= OPT_INFO;
			break;
		case 'n':
			opt |= OPT_NO_SENSORS;
			break;
		case 'r':
			opt |= OPT_RECORD;
			break;
		case 'b':
			opt |= OPT_BATCH;
			break;
		case 'c':
			opt |= OPT_COMMAND;
			break;
		}
	}
	if (idx < -1) {
		fprintf(stderr, "%s: %s\n",
		        poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
		        poptStrerror(idx));
		exit(opt);
	}
	if (opt & OPT_ABOUT) {
		about();
		exit(0);
	}
	if (opt & OPT_TRACE) {
		trace_init(trace_level);
	} else {
		trace_init(0);
	}

	if (opt & OPT_INFO) {
		sio_info();
		exit(0);
	}
	if (opt & OPT_NO_SENSORS) {
		sensor_hal_set_no_sensors(true);
		printf("No sensors enabled\n");
	}
	if (opt & OPT_RECORD) {
		rec_init();
		rec_start(fn_rec);
		printf("Recording enabled. Filename: %s\n",fn_rec);
	}
	if (opt & OPT_BATCH) {
		sensor_hal_set_use_batch(false);
		printf("Batch disabled\n");
	}
	if (opt & OPT_COMMAND) {
		sio_command(cmd);
		exit(0);
	}


//------------------------------------------------------------------------------
//  Application initialization
//------------------------------------------------------------------------------
	glutInit(&argc, argv);														/* Initialize GLUT */
	glutInitWindowSize(WIN_SZ_WIDTH, WIN_SZ_HEIGHT);							/* set window size */
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);					/* set display mode */
	glutCreateWindow("NXP sensorhub demo");										/* create a window */

	glutReshapeFunc(resize_callback);											/* register callback for window resize */
	glutDisplayFunc(draw_callback);												/* register callback for window redraw */
	glutTimerFunc(refresh_get(), timer_callback, 0);							/* register callback for a timer */

	gl_menu_init();																/* initialize the menu */
	gl_menu_create();															/* create menu and callbacks */
	gl_text_init(WIN_SZ_WIDTH, WIN_SZ_HEIGHT);									/* initialize 2D text */
	auto_rotate_init();															/* auto-rotate initilization */
	teapot_init();																/* set initial OpenGL state for teapot */

	sensor_hal_init();															/* initialize the sensor hal */
	sensor_hal_open(port);														/* open sensor hub */

	glutMainLoop();																/* start the main event loop */
	rec_stop();																	/* close out recording file if it's open */
}
